#! /usr/bin/env python
"""
    Adelide - A virtual media bookshelf.
    Copyright (C) Jonas Aronsson - jonas@zxvf.se, Niklas Johansson jonikl@ituniv.se

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
"""

import gtk
import gobject
from adelib import media
from sqlite3 import dbapi2 as sqlite
from db import databaseHandler

## this class handels all logic of the adelide software
#
class my_gui:

    ## populate_combo_type creates and populates the combobox with the types of media in the database
    #
    # @param self specifies the current object 
    # @param box the box the media types will be added to
    def populate_combo_type(self, box):
        combo_list = gtk.ListStore(gobject.TYPE_STRING)
        box.set_model(combo_list)
        cell = gtk.CellRendererText()
        box.pack_start(cell, True)
        
        cursor = db.get_media_types()
        
        box.add_attribute(cell, "text", 0)
        box.append_text("All Media")
        
        for row in cursor:
            box.add_attribute(cell, "text", 0)
            box.append_text(row[2])
        
        box.set_active(0)

    ## __init__ is the constructor of adelide
    # it creates the main window
    #
    # @param self specifies the current object
    def __init__(self):
        # create from glade-file
        builder = gtk.Builder()
        builder.add_from_file("gui/adelide.xml")
        self.window = builder.get_object("window")
        self.add = builder.get_object("button_add")
        self.delete = builder.get_object("button_delete")
        self.search_text = builder.get_object("entry_search")
        self.main_view = builder.get_object("main_view")
        self.list_store = gtk.ListStore(object)
        self.label_items = builder.get_object("label_items")
        
        # combo box...
        self.combo_type = builder.get_object("combobox_type")
        self.populate_combo_type(self.combo_type)
        
        # connect all...
        builder.connect_signals(self)
        
        # fill textbox with all media
        self.searcher('')
        

    ## searcher fills the tree on the main page of the program 
    # 
    # @param self specifies the current object 
    # @param arr is the object found in the database 
    def searcher(self, arr):
        #cursor = db.do_search(arr)
        self.fill_tree(db.do_search(arr))        


    ## fill_tree is used by the seacher function to fill the the tree 
    # on the main page of the program 
    # building collumns and cells for the entries
    #
    # @param self specifies the current object 
    # @param cursor is the connection to the database holding all the values.
    def fill_tree(self, cursor):
        for column in self.main_view.get_columns():
            self.main_view.remove_column(column)
        
        self.list_store.clear()
        
        if cursor != [-1]:
            for new_media in cursor:
                self.list_store.append([new_media])
            self.label_items.set_text(str(len(self.list_store)))        

            self.cell = gtk.CellRendererText()
            self.title_column = gtk.TreeViewColumn('Title', self.cell)
            self.human_column = gtk.TreeViewColumn('Humans', self.cell)
            self.type_column = gtk.TreeViewColumn('Type_id', self.cell)
            self.year_column = gtk.TreeViewColumn('Year', self.cell)
            self.publisher_column = gtk.TreeViewColumn('Publisher_id', self.cell)
            self.ean_column = gtk.TreeViewColumn('EAN', self.cell)
            self.rating_column = gtk.TreeViewColumn('Rating', self.cell)
            self.fav_column = gtk.TreeViewColumn('Favorite', self.cell)
            
            self.title_column.set_cell_data_func(self.cell, self.cell_data_func, 'title')
            self.human_column.set_cell_data_func(self.cell, self.cell_data_func, 'humans')
            self.type_column.set_cell_data_func(self.cell, self.cell_data_func, 'type_id')
            self.year_column.set_cell_data_func(self.cell, self.cell_data_func, 'year')
            self.publisher_column.set_cell_data_func(self.cell, self.cell_data_func, 'publisher_id')
            self.ean_column.set_cell_data_func(self.cell, self.cell_data_func, 'ean')
            self.rating_column.set_cell_data_func(self.cell, self.cell_data_func, 'rating')
            self.fav_column.set_cell_data_func(self.cell, self.cell_data_func, 'favorite')
            
            self.main_view.insert_column(self.title_column, 0)
            self.main_view.insert_column(self.human_column, 1)
            self.main_view.insert_column(self.type_column, 2)
            self.main_view.insert_column(self.year_column, 3)
            self.main_view.insert_column(self.publisher_column, 4)
            self.main_view.insert_column(self.ean_column, 5)
            self.main_view.insert_column(self.rating_column, 6)
            self.main_view.insert_column(self.fav_column, 7)
        else:
            empty_media = media.Media()
            empty_media.title = "No such media found!"
            self.list_store.append([empty_media])
            
            self.cell = gtk.CellRendererText()
            self.title_column = gtk.TreeViewColumn('Title', self.cell)
            self.title_column.set_cell_data_func(self.cell, self.cell_data_func, 'title')
            self.main_view.insert_column(self.title_column, 0)
        
        self.main_view.set_model(self.list_store)
        self.main_view.show_all()

    ## cell_data_func will update the information in the cells  
    #
    # @param self specifies the current object 
    # @param column current column 
    # @param, cell current cell
    # @param model list model for the tree view, which contains objects 
    # @param itr iterator which is used to find the attribute
    # @param attr specifies which attribute should be fetched from the object 
    def cell_data_func(self, column, cell, model, itr, attr):
        obj = model.get(itr,0)[0]
        cell.set_property('text', str(getattr(obj, attr)))
    
    
    ## on_entry_search_activate will activate the search for the specified media
    #
    # @param self specifies the current object 
    # @param *args is used for storing arguments from signal sender
    def on_entry_search_activate(self, *args):
        text = self.search_text.get_text()
        if text == 'Search':
            text = ''
        self.searcher(text)
    
    
    ## on_entry_search_focus_in_event provides the user with automatic letter search 
    # the function will sort the search depending on the user entry 
    #
    # @param self specifies the current object 
    # @param *args is used for storing arguments from signar sender
    def on_entry_search_focus_in_event(self, *args):
        if self.search_text.get_text() == 'Search':
            self.search_text.set_text('')
    
    
    ## on_entry_search_focus_out_event will display the word "Search" in the search fild
    # when there is no search ongoing 
    #
    # @param self specifies the current object
    # @param *args is used for storing arguments from signal sender
    def on_entry_search_focus_out_event(self, *args):
        if self.search_text.get_text() == '':
            self.search_text.set_text('Search')
         
         
    ## on_input_button_add_clicked gets all the information the user put into the add fields 
    # the last row of this function is sends then the information to the database making a new entry
    #
    # @param self specifies the current object 
    # @param *args is used for storing arguments from signal sender
    def on_input_button_add_clicked(self, *args):
        favorite = 0
        
        if self.input_checkbox_favorite.get_active():
            favorite = 1
        
        new_media = media.Media()

        new_media.title = self.input_title.get_text()
        new_media.year = self.input_year.get_text()
        new_media.cover = self.input_cover.get_text()
        new_media.ean = self.input_ean.get_text()
        new_media.rating = self.input_rating.get_text()
        new_media.favorite = favorite
        new_media.format_id = self.input_format.get_text()
        new_media.type_id = self.input_type.get_text()
        new_media.studio_id = self.input_studio.get_text()
        new_media.publisher_id = self.input_publisher.get_text()

        db.add_to_db(new_media)

    ## on_button_add is invoced when the user presses the "add" button
    # it builds the add window 
    # 
    # @param self specifies the current object 
    # @param *args is used for storing arguments from signal sender
    def on_button_add_clicked(self, *args):
        input_builder = gtk.Builder()
        input_builder.add_from_file("gui/input.xml")
        self.input_window = input_builder.get_object("input_window")
        self.input_title = input_builder.get_object("input_title")
        self.input_year = input_builder.get_object("input_year")
        self.input_cover = input_builder.get_object("input_cover")
        self.input_studio = input_builder.get_object("input_studio")
        self.input_publisher = input_builder.get_object("input_publisher")
        self.input_ean = input_builder.get_object("input_ean")
        self.input_rating = input_builder.get_object("input_rating")
        self.input_format = input_builder.get_object("input_format")
        self.input_type = input_builder.get_object("input_type")
        self.input_checkbox_favorite = input_builder.get_object("input_favorite")
        self.input_button_add = input_builder.get_object("input_button_add")
        
        input_builder.connect_signals(self)
        
        
    ## on_button_delete_clicked will remove the marked media entry from the database
    #
    # @param self specifies the current object
    # @param *args is used for storing arguments from signal sender
    def on_button_delete_clicked(self, *args):
        selected = self.main_view.get_selection().get_selected()
        del_media = selected[0].get_value(selected[1], 0)
        db.delete_media(del_media.media_id)
        self.display_all_of_type(del_media.type_id)
        
        
    ## on_window_destroy this function will close the gtk windows
    # 
    # @param self specifies the current object
    # @param widget is the widget window
    # @param data is set to None
    def on_window_destroy(self, widget, data=None):
        gtk.main_quit()


    ## display_all_of_type will search all media entries for a specific type_id 
    # e.g.: Music, Books, Film or Games
    # 
    # @param self specifies the current object
    # @param *args is used for storing arguments from signal sender
    def display_all_of_type(self, type_id):
        cursor = db.search_media_types(type_id)
        self.fill_tree(cursor)


    ## on_combobox_type_changed will change the all media entries for a specific media type
    # this function does the updating by calling the display_all_of_type function
    #
    # @param self specifies the current object
    # @param combo_type is the locally kept combobox
    def on_combobox_type_changed(self, combo_type):
        model = combo_type.get_model()
        index = combo_type.get_active()
        if index >= 0:
            if index > 0:
                self.display_all_of_type(index)
            else:
                self.searcher('')
            self.combo_type.set_active(index)
        
## this function will start the program
if __name__ == "__main__":
    db = databaseHandler.databaseHandler()
    editor = my_gui()
    editor.window.show()
    gtk.main()
    
